﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WheelOfCivilization.Map.MapObject.Movable;
using Microsoft.Xna.Framework;
using System.Threading;
using WheelOfCivilization.Logic;
using WheelOfCivilization.Map.MapObject.Unmovable.Nature;
using WheelOfCivilization.Map.MapObject.Unmovable.Buildings;

namespace WheelOfCivilization.Map
{
    class Villager : MovingObject
    {
        public Villager()
        {
            this.eyeRange = 4;
        }
        public Point position;
        private int capacity = 10;
        private int carrying = 0;
        private NatureObject pocket;
        override public bool moving { get; set; }
        override public WorldCluster inCluster { get; set; }

        public override bool selected { get; set; }

        public override void move(Logic.Route totalRoute)
        {
            this.moving = true;
            
            for (int i = 0; i < totalRoute.worldRoutes.Count; i++)
            {
                if (this.inCluster != totalRoute.worldRoutes.ElementAt(i))
                {
                    this.inCluster.unitsGS.Remove(this);
                    this.inCluster.movableContentGS.Remove(this);
                    this.inCluster = totalRoute.worldRoutes.ElementAt(i);
                    this.inCluster.unitsGS.Add(this);
                    this.inCluster.movableContentGS.Add(this);
                }
                for (int j = 0; j < totalRoute.clusterRoutes.ElementAt(i).Count; j++)
                {
                    this.position.X = totalRoute.clusterRoutes.ElementAt(i).ElementAt(j)[0];
                    this.position.Y = totalRoute.clusterRoutes.ElementAt(i).ElementAt(j)[1];
                    Control.searchNeigborhood(this);
                    Thread.Sleep(500);
                }
            }
            this.moving = false;
        }

        public override string ToString()
        {
            return "villager";
        }

        public override Point pos
        {
            get
            {
                return this.position;
            }
            set
            {
                this.position = value;
            }
        }

        public override void move(Route totalRoute, object invokeAction)
        {
            move(totalRoute);
            WorldObject reTypedForAction = (WorldObject)invokeAction;

            var startAction = new Dictionary<Type, Action>{
                { typeof(NatureObject), () => mineResources(invokeAction) },
                { typeof(BuildingObject), () => handResources(invokeAction) },
                { typeof(Ground), () => handResources(invokeAction) },
            };
            startAction[reTypedForAction.GetInfo()]();
        }

        private void handResources(object invokeAction)
        {
            Program.playerResources.wood += this.carrying;
            this.carrying = 0;
            searchForSource(pocket);
        }

        private void mineResources(object invokeAction)
        {
            pocket = (NatureObject)invokeAction;
            while (carrying < capacity)
            {
                if (pocket.value < 1)
                    break;
                carrying++;
                pocket.value--;
            }
            if (carrying < capacity)
            {
                searchForSource(pocket);
            }
            else
            {
                searchForRepository(pocket);
            }
        }

        private void searchForRepository(NatureObject pocket)
        {
            Point mapDistance = new Point();
            Point clusterDistance = new Point();
            double distance = double.MaxValue;
            BuildingObject target = null;
            foreach (BuildingObject repository in Program.playerResources.buildingsP)
            {
                mapDistance.X = (this.inCluster.X - repository.inCluster.X) * 10;
                mapDistance.Y = (this.inCluster.Y - repository.inCluster.Y) * 10;
                double tmpDistance = MovementLogic.routeLength(new Point(0,0), mapDistance) + MovementLogic.routeLength(this.pos, repository.position);
                if(distance > tmpDistance)
                {
                    distance = tmpDistance;
                    target = repository;
                }
            }
            MovementLogic.Move(this, target, true);
        }

        private void searchForSource(NatureObject pocket)
        {
            throw new NotImplementedException();
        }
    }
}
